package pzl.kt.study.base

import org.junit.Test
import java.io.File
import java.util.*

class HELLO_WORLD {

    @Test
    fun main() {
        println("hello kt ")

        //中文友好型命名 为啥不用呢
        var 中文变量 = "可以滴"
        println(中文变量)

        //2种写法等价
        var a1: Int = 5
        var a2 = 5

        //4字节
        var 浮点单精度小数 = 1.234f
        //8字节
        var 双精度小数 = 1.234

        var 二进制数 = 0b10101
        var 十六进制数 = 0xABC

        println("这个二进制数是 ：" + 十六进制数)
        println("这个二进制数是 ：$十六进制数")

        //Kotlin不支持自动扩展数字范围，转换必须手动进行
        var number1 = 10 //默认int
        println("number1 =$number1")
        var number2 = number1.toLong() //手动转换
        println("number2 =$number2")

        var num1 = 1.23f
        println("num1 =$num1")
        var num2 = num1.toDouble() //手动转换
        println("num2 =$num2")


        //位运算
        val 一左移二 = 1 shl 2
        val 一右移二 = 1 shr 2
        val 一无符号右移二 = 1 ushr 2
        //逻辑运算
        val 一逻辑与1111 = 1 and 0x00001111
        val 一异或1111 = 1 xor 0x00001111
        val 一取反 = 1.inv()
        println("一左移二 = $一左移二")
        println("一右移二 = $一右移二")
        println("一无符号右移二 = $一无符号右移二")
        println("一逻辑与1111 = $一逻辑与1111")
        println("一异或1111 = $一异或1111")
        println("一取反 = $一取反")

        //小数 默认为double类型
        var 一个双进度数字 = 1.56789
        var c: Int = 一个双进度数字.toInt() //注意不是四舍五入，是直接砍掉小数部分
        println("c = $c")

    }


    @Test
    //元组（Tuple）：一个变量能同时赋予多个值
    fun tuple() {
        var 水 = Pair("硬水", "软水")//二元组，最多赋值2个
        var 课程 = Triple("kotlin实战", 1200, false)//三元组，最多赋值3个
        println("水 = $水")
        println("${水.first}     ${水.second}")
        println("课程名称：${课程.first}  课程价格：${课程.second}  课程vip:${课程.third}")
    }


    //可空类型
    @Test
    fun nullable() {
        var name: String? = null
        println("name = ${name}")
    }

    //对象的构造
    @Test
    fun 构造() {
        var f = File("不存在的路径")
        println(f.exists())
        var date = Date(System.currentTimeMillis())
        println(date.toLocaleString())
    }

    //引用相等与结构相等
    @Test
    fun 引用相等与结构相等() {
        var f1 = File("根路径/子路径/孙子路径")
        var f2 = File("根路径/子路径/孙子路径")

        println("引用相等判断：" + (f1 === f2))
        println("结构相等判断：" + (f1 == f2))

        println(f1 !== f2)
        println(f1 != f2)
    }

    //range区间
    @Test
    fun 区间() {
        var 区间a到z = "a".."z"
        println(区间a到z.toString())
        println(区间a到z.start)
        var 在里面么1 = 区间a到z.contains("s")
        println(在里面么1)
        println(区间a到z.contains("!"))

        var 区间2 = 1..1000
        println()
        println(区间2.contains(999))
        println(区间2.contains(9991))

        //倒序区间
        var 区间3 = 10.downTo(0)
        for (d in 区间3) {
            println("print 区间3 = " + d)
        }
        var 区间4 = 0.rangeTo(10)
        println()
        for (d in 区间4) {
            println("print 区间4 = " + d)
        }

        //步进2，倒序
        var 区间5 = (1..20).step(2).reversed()
        println()
        for (d in 区间5) {
            println("print 区间5 = " + d)
        }

        var 区间6 = (1..20).reversed()
        println()
        for (d in 区间6) {
            println("print 区间6 = " + d)
        }
    }


    // when ,加强版switch
    @Test
    fun testWhen() {
        //1.可以返回值
        println("\n" + when1(3))
        //2.可以合并分支
        println("\n" + when2(2))
        //3.case 可以使用函数
        println("\n" + when3(5))
        //4.可以运行时对类型智能转换
        println("\n类型智能转换 " + isString(""))
        println("类型智能转换 " + isString(1))
        //5.无参的when,对多分支的if else的替换，美观
        println("\n" + when4(1, 2))
        //综合
        println("\n"+when5(5))
        println("\n"+when5("ddd"))
    }

    fun when1(x: Int): Boolean {
        var 是极大值或极小值么 = when (x) {
            Int.MAX_VALUE -> true
            Int.MIN_VALUE -> true
            else -> false
        }
        return 是极大值或极小值么
    }

    fun when2(x: Int) {
        when (x) {
            Int.MAX_VALUE, Int.MIN_VALUE -> {
                println("$x 满足要求")
            }
            else -> {
                println("$x 不满足要求")
            }
        }
    }

    fun when3(x: Int) {
        when (x) {
            Math.abs(x) -> println("$x Math.abs(x)")
            in 0..10 -> println("$x in 0..10")
            else -> println("$x else")
        }
    }

    //when能返回值
    fun isString(anyData: Any) = when (anyData) {
        is String -> true
        else -> false
    }

    //when能返回值
    fun isString2(anyData: Any): Boolean {
        return when (anyData) {
            is String -> true
            else -> false
        }
    }

    fun when4(a: Int, b: Int) {
        when {
            a > b -> println("$a 大于 $b")
            a < b -> println("$a 小于 $b")
            else -> println("$a 等于 $b")
        }
    }

    fun when5(any: Any) {
        when (any) {
            in 1..6 -> {
                println("处于1到6")
            }
            -1, -2, -3 -> {
                println("-1,-2,-3 之一")
            }
            (10 - 2) -> {
                println("值为8")
            }
            is Int -> {
                println("是Int类型")
            }
            else -> {
                println("是其它类型的")
            }
        }
    }

    //嵌套函数和函数返回
    @Test
    fun testFunNestedAndReturn() {
        println("最大值 = " + getMaxValueIn3Input(1, 2, 3))
        println(找到小于9的数字())
    }

    fun getMaxValueIn3Input(a: Int, b: Int, c: Int): Int {
        //内部嵌套函数
        fun getMaxValueIn2Input(c: Int, d: Int): Int {
            if (c > d) return c
            return d
            //从最近的嵌套函数或匿名函数回，只会退出最内层的函数
        }
        return getMaxValueIn2Input(getMaxValueIn2Input(a, b), getMaxValueIn2Input(b, c))
    }


    fun 找到小于9的数字() {
        var list = listOf(-1, 0, 4, 5, 9, 44, 200, 5000)
        list.forEach(
            fun(it) {
                if (it < 9) println("$it 小于9")
                return
            }
        )
        println("这句话会被打印出来")
    }


    fun 类型层级() {
        //Any -> Object
        //Unit -> Void
        //Nothing 所有类型的子类
    }


    //循环遍历
    @Test
    fun testIterator() {
        var customBean = CustomBean()
        customBean.add("111")
        customBean.add("222")
        customBean.add("333")
        customBean.add("444")
        customBean.add("555")
        for (itemStr in customBean) {
            println(itemStr)
        }
    }

}